//
//  Simulation.h
//  phy_four
//
//  Created by Snir Gazit on 3/12/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#ifndef phy_four_Simulation_h
#define phy_four_Simulation_h

#include "../HelpLibs/def.h"
#include "Lattice.h"
#include "Move.h"
#include "Measure.h"
#include "../HelpLibs/RandomGen.h"
#include "../HelpLibs/QmcParameters.h"
#include "../HelpLibs/pugixml/pugixml.hpp"
#include "boost/chrono.hpp"
#include <gsl/gsl_sf_hyperg.h>
#include <gsl/gsl_sf_gamma.h>
#include <iostream>
#include "../HelpLibs/InputFile.h"
namespace ba = boost::accumulators;
double calcWR(double mu, double U, int m);
void calcWeight(double muIn, double UIn, double g, int maxBond,
		ostream &outFile, BoltzWeightType &weightR);
double calcWRGauss(double mu, int m);
void calcWeightGauss(double muIn, double g, int maxBond,
		ostream &outFile, BoltzWeightType &weightR);
// Worm Algorithm

class OnModel {
	// Params
	QmcParameters qmcParameters_;
	// Configuration
	Lattice lat_;
	// Moves
	ShiftMove shiftMove_;
	CreatePairMove createPairMove_;
	// Measurements
	Measurements measures_;
	// Random Number Engine
	MTGen eng_;
	// LoopType
	UniIntVariable chooseLoopType_;
	// OufPutFile
	ofstream outFile_;
	// Loop Type
	boost::array<acc,NF> wormLength_;
	BoltzWeightType boltzWeight_;
public:
	~OnModel();
	void init(QmcParameters &qmcParameters);
	bool run();
	void thermalize();
	bool checkNotDone();
	void nextMove();
	void simulatedAnnealing();
	void setCoupeling(double g);
	void dump(bool final);
	void read();
};

#endif
